#!/usr/bin/python2
# -*- coding: utf-8 -*-


# import threading
import time
import random
import numpy as np

# from Queue import Queue
from eventlet import Queue,sleep

from FatTreeSim import FatTreeSim
from updatewrapper import UpdateWrapper


class MockUpdateGenerator():
    def __init__(self,queue,topo,poisson_lambda= 1):
        assert isinstance(queue,Queue)
        # assert isinstance(topo,FatTreeSim)
        self.__queue = queue
        self.__lambda = poisson_lambda
        self.__topo = topo

    def run(self):
        sleep(5)
        UPDATENUM = 200
        random.seed(88)
        poisson_interval = []
        while len(poisson_interval)<UPDATENUM:
            rand = random.expovariate(self.__lambda)
            if rand>0.1 and rand<1.0/self.__lambda*3:
                poisson_interval.append(rand)
        print("poisson_interval",poisson_interval)

        random.seed(888)
        hosts = self.__topo.hosts.keys()
        # update {(1,2): [ 1,2,3], (3,4):[1,2,3], "starttime" }
        updates = []
        hosts_len = len(hosts)
        host_pairs = [(hosts[i],hosts[j]) for i in range(hosts_len) for j in range(hosts_len) if i!=j]
        l = len(host_pairs)//3
        pairs1 = host_pairs[0:l]
        pairs2 = host_pairs[l:]
        pvalue = 0.3

        while len(updates)<UPDATENUM:
            random.shuffle(pairs1)
            random.shuffle(pairs2)
            m = int(pvalue*l)
            new_pairs1 = list(pairs1[0:m])
            new_pairs1.extend(pairs2[0:l-m])
            new_pairs2 = list(pairs1[m:])
            new_pairs2.extend(pairs2[l-m:])
            pairs1 = new_pairs1
            pairs2 = new_pairs2
            update = {}
            a = random.randint(l*3/4,l)
            for p in pairs1[0:a]:
                paths = self.__topo.shortest_paths(*p)
                update[p] = paths[random.randint(0,len(paths)-1)]
            updates.append(update)
            print("update",len(updates),update)

        sleep(5)
        print("start!!")
        for i in range(UPDATENUM):
            self.__queue.put(UpdateWrapper(updates[i]))
            sleep(poisson_interval[i])
            # sleep(1.0/self.__lambda)
